/**
 * @file 浏览器管理服务
 * @description 负责管理多个浏览器窗口实例的核心服务
 * @author 黄敏
 * @创建时间 2025-07-28
 **/

import type { Tab } from '#/browser/entities/tab.entity'
import type { WebContents } from 'electron'
import { WindowController } from '#/browser/controllers/window.controller'
import { ipcMain } from 'electron'
import { browserTopic } from '~shared/ipc-topic'

/**
 * 浏览器管理服务类
 *
 * 负责管理多个浏览器窗口的生命周期，包括创建、销毁、标签页移动等操作
 *
 * @class BrowserManager
 * @description 提供浏览器窗口的统一管理接口，处理窗口间的协调和事件分发
 * @author 黄敏
 * @version 2.0.0
 * @since 2025-07-28
 */
export class BrowserManager {
  private static instance: BrowserManager

  /** 主浏览器窗口 */
  private readonly mainWindow = new WindowController(true)

  /** 其他浏览器窗口数组 */
  private readonly otherWindows: WindowController[] = []

  /**
   * 获取单例实例
   */
  static getInstance(): BrowserManager {
    if (!BrowserManager.instance) {
      BrowserManager.instance = new BrowserManager()
    }
    return BrowserManager.instance
  }

  /**
   * 私有构造函数，确保单例模式
   */
  private constructor() {
    this.registerIpcHandlers()
  }

  /**
   * 注册IPC事件处理器
   */
  private registerIpcHandlers() {
    // 创建浏览器窗口
    ipcMain.on(browserTopic.addBrowser, (_, tabIds?: number[] | string) => {
      console.log('🚀 创建浏览器窗口', tabIds)
      this.createNewWindow(tabIds ?? '')
    })

    // 移动标签页到该浏览器
    ipcMain.on(browserTopic.moveTabs, (_, tabIds: number[]) => {
      const tabs = this.moveTabsToNewBrowser(tabIds)
      this.getWindowByWebContents(_.sender).tabManager.topTabController.addTabs(tabs)
    })
  }

  /**
   * 获取所有浏览器窗口
   */
  getAllWindows(): WindowController[] {
    return [this.mainWindow, ...this.otherWindows]
  }

  /**
   * 通过WebContents获取对应的浏览器窗口实例
   * 优化：先检查主浏览器，减少不必要的遍历
   * @param webContents - WebContents实例
   * @returns 对应的浏览器窗口实例，如果未找到则返回主浏览器窗口
   */
  getWindowByWebContents(webContents: WebContents): WindowController {
    // 优先检查主浏览器，因为大多数操作都在主浏览器
    if (this.mainWindow.getTabByWebContents(webContents)) {
      return this.mainWindow
    }

    // 在其他浏览器中查找
    const window = this.otherWindows.find(window => window.getTabByWebContents(webContents))

    // 如果未找到，返回主浏览器作为默认值
    return window || this.mainWindow
  }

  /**
   * 创建新的浏览器窗口
   * @param tabIds - 标签页ID数组或URL字符串
   */
  createNewWindow(tabIds?: number[] | string): void {
    try {
      let tabs: Tab[] | string | undefined
      if (Array.isArray(tabIds)) {
        tabs = this.moveTabsToNewBrowser(tabIds)
        if (tabs[0]) {
          tabs[0].data.autoFocus = true
        }
      } else {
        tabs = tabIds
      }

      const newBrowserWindow = new WindowController(false, tabs)
      // 监听浏览器窗口关闭事件，确保从数组中移除
      newBrowserWindow.onClosed(() => {
        const index = this.otherWindows.indexOf(newBrowserWindow)
        if (index !== -1) {
          this.otherWindows.splice(index, 1)
        }
      })

      this.otherWindows.push(newBrowserWindow)

      console.log(`✅ 创建新浏览器窗口成功，当前共有 ${this.otherWindows.length} 个浏览器窗口`)
    } catch (error) {
      console.error('❌ 创建浏览器窗口时发生错误:', error)
    }
  }

  /**
   * 将指定ID的标签页移动到新浏览器
   * @param tabIds - 要移动的标签页ID数组
   * @returns 成功移动的标签页数组
   */
  private moveTabsToNewBrowser(tabIds: number[]): Tab[] {
    const movedTabs: Tab[] = []
    const allBrowserWindows = this.getAllWindows()

    for (const browserWindow of allBrowserWindows) {
      const tabs = browserWindow.tabManager.topTabController.transferTabs(tabIds)
      if (tabs) {
        movedTabs.push(...tabs)
        break
      }
    }

    console.log(`✅ 成功移动 ${movedTabs.length} 个标签页到新浏览器窗口`)
    return movedTabs
  }
}
